//
//  ViewController.m
//  TCPSocketClient
//
//  Created by scasy_wang on 16/10/20.
//  Copyright © 2016年 scasy_wang. All rights reserved.
//

#import "ViewController.h"
#import "AsyncSocket.h"
#import "SwitchHeader.h"

/**
 *  包头自定义协格式  重要
 */
typedef struct {
    Byte version;
    Byte Mask;
    Byte cmdByte;
    Byte bodyLen[4];
}SendDataHead;

@interface ViewController ()<AsyncSocketDelegate>
@property(nonatomic,strong)AsyncSocket *tcpScoket;
@property (weak, nonatomic) IBOutlet UITextField *hostTF;
@property (weak, nonatomic) IBOutlet UITextField *portTF;
@property (weak, nonatomic) IBOutlet UITextView *textV;
@property (weak, nonatomic) IBOutlet UITextField *sendTF;

///读取到的数据
@property (strong, nonatomic) NSMutableData *readData;
@property (nonatomic, strong) NSMutableArray *connectHostMuArr;
@property (nonatomic, strong) NSArray *sendHostArr;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.connectHostMuArr = [NSMutableArray array];
    self.hostTF.text = @"192.168.179.105";
    self.portTF.text = @"8888";
    self.tcpScoket = [[AsyncSocket alloc]initWithDelegate:self];
    
    // Do any additional setup after loading the view, typically from a nib.
}

- (IBAction)doConnect:(id)sender {
    
    NSError *error;
    BOOL isConnect = [self.tcpScoket connectToHost:self.hostTF.text onPort:[self.portTF.text intValue] withTimeout:-1 error:&error];
    if (isConnect) {
        NSLog(@"连接成功");
    }else {
        NSLog(@"连接失败");
    }
    
    //[self.tcpScoket setRunLoopModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
    [self.tcpScoket readDataWithTimeout:-1 tag:0];
}


- (IBAction)doSend:(id)sender {
    [self.view endEditing:YES];
    
    
    //构造消息内容
    NSDate *datenow = [NSDate date];//现在时间
    NSString *timenow=[self getNowTimeTimestamp3];
    NSString *contenttemp=@"{\"from\": \"%@\",\"to\": \"%@\",\"cmd\":\"%@\",\"createTime\": \"%@\",\"msgType\": \"%@\",\"chatType\":\"%@\",\"group_id\":\"%@\",\"content\": \"%@\"}";
    NSString *content=[NSString stringWithFormat:contenttemp,@"hello_ios", @"admin",@"11",timenow,@"0",@"1",@"100",self.sendTF.text];

    
    //发送消息方法
    [self sendMessage:content cmd:(Byte)11];
    
    self.sendTF.text=@"";
}

-(NSString *)getNowTimeTimestamp3{
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
    
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    
    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss SSS"]; // ----------设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制
    
    //设置时区,这个对于时间的处理有时很重要
    
    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];
    
    [formatter setTimeZone:timeZone];
    
    NSDate *datenow = [NSDate date];//现在时间,你可以输出来看下是什么格式
    
    NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]*1000];
    
    return timeSp;
}

//发送socket消息
-(void)sendMessage:(NSString *)content cmd:(Byte)cmd{
    //要发送的总体数据
    NSMutableData *mData = [[NSMutableData alloc] init];
    
    //消息体内容 转换成nsdata即可。连接上服务器后，首先需要登录，发送账号密码过去.json格式。
    NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
    
    NSInteger datalenth =data.length;  //获取消息体内容转换成nsdata后的长度
    
    SendDataHead senddata;
    senddata.version=0x01; //协议版本号 目前为1
    senddata.Mask=0x81;    //mask数据。目前固定
    //senddata.cmdByte=0x05; //消息cmd命令。。根据消息类型不同而不同。例如登录操的cmd为0x05
    senddata.cmdByte=cmd;
    
    //以下是拼接 消息内容的长度 转换成字节放到包头里面 消息体长度占四个字节。是个int数据
    senddata.bodyLen[0]=(Byte)((datalenth & 0xFF000000)>>24);
    senddata.bodyLen[1]=(Byte)((datalenth & 0x00FF0000)>>16);
    senddata.bodyLen[2]=(Byte)((datalenth & 0x0000FF00)>>8);
    senddata.bodyLen[3]=(Byte)((datalenth & 0x000000FF));
    
    //将包头内容转换成nsddata
    NSData * headdata = [[NSData alloc]initWithBytes:&senddata length:sizeof(SendDataHead)];
    
    
    [mData appendData:headdata]; //拼放入包头
    [mData appendData:data];   //放入消息体
    
    [self.tcpScoket writeData:mData withTimeout:-1 tag:0];  //写入数据
}

-(void)addMessage:(NSString *)str{
    self.textV.text = [self.textV.text stringByAppendingFormat:@"%@\n\n\n",str];
    [self.textV scrollRangeToVisible:[self.textV.text rangeOfString:str options:NSBackwardsSearch]];
}

//AsyncSocketDelegate
//已经连接上
-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{
    
    [self addMessage:[NSString stringWithFormat:@"连接上%@\nlocal:%@",host,sock]];
    [self.connectHostMuArr addObject:host];
    [self.tcpScoket readDataWithTimeout:-1 tag:0];
    
    //连接成功后，发送账号密码登录
    NSString *content=@"{\"loginname\":\"hello_ios\",\"password\":\"123\"}";
    [self sendMessage:content cmd:0x05];
    
}

-(void)onSocketDidDisconnect:(AsyncSocket *)sock{
}

-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    NSData *head = [data subdataWithRange:NSMakeRange(0, 7)];//取得包头头部数据  包头目前长度是7位
    NSData *lengthData = [head subdataWithRange:NSMakeRange(3, 4)];//取得长度数据 第3-4位是消息体长度  此处和发送包时拼接的头包的格式是一样的
    
    //以下是将包头的长度的四个字节转换成int数字。
    NSString* hexString = [lengthData convertDataToHexStr];
    NSInteger length = [[hexString hexToDecimal]integerValue];
    
    //从第8个字符节开始一直到length长度的数据，都是消息体正文。
    NSData *contentdata=[data subdataWithRange:NSMakeRange(7, length)];
    
    NSString *msg = [[NSString alloc] initWithData: contentdata encoding:NSUTF8StringEncoding];
    NSLog(@"读到的数据：%@",msg);
    [self addMessage:[NSString stringWithFormat:@"收到数据：%@",msg]];
    [self.tcpScoket readDataWithTimeout: -1 tag: 0];
}


-(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag{
//    [self addMessage:[NSString stringWithFormat:@"发送了"]];
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.view endEditing:YES];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/** 读取字节 */
- (int8_t)readRawByte:(NSData *)data headIndex:(int32_t *)index{
    
    if (*index >= data.length) return -1;
    
    *index = *index + 1;
    
    return ((int8_t *)data.bytes)[*index - 1];
}
@end

